#pragma once
#include <iostream>
#include <unordered_map>
#include <string>

namespace MyRpc
{
    // 定义json类型中的key数据
    #define KEY_METHOD      "method"
    #define KEY_PARAMS      "parameters"
    #define KEY_TOPIC_KEY   "topic_key"
    #define KEY_TOPIC_MSG   "topic_msg"
    #define KEY_OPTYPE      "optype"
    #define KEY_HOST        "host"
    #define KEY_HOST_IP     "ip"
    #define KEY_HOST_PORT   "port"
    #define KEY_RCODE       "rcode"
    #define KEY_RESULT      "result"

    // 发布订阅所包含的请求操作
    enum class TopicRequestOpType
    {
        TOPIC_CREATE = 0,
        TOPIC_REMOVE,
        TOPIC_SUBSCRIBE,
        TOPIC_CANCEL,
        TOPIC_PUBLISH
    };

    // 请求类型
    enum class MType 
    {
        REQ_RPC = 0,
        RSP_RPC,
        REQ_TOPIC,
        RSP_TOPIC,
        REQ_SERVICE,
        RSP_SERVICE
    };

    // 响应码的定义
    enum class RCode 
    {
        RCODE_OK = 0,
        RCODE_PARSE_FAILED,
        RCODE_ERROR_MSGTYPE,
        RCODE_INVALID_MSG,
        RCODE_DISCONNECTED,
        RCODE_INVALID_PARAMS,
        RCODE_NOT_FOUND_SERVICE,
        RCODE_INVALID_OPTYPE,
        RCODE_NOT_FOUND_TOPIC,
        RCODE_INTERNAL_ERROR
    };

    static std::string errReason(const RCode& code)
    {
        static std::unordered_map<RCode, std::string> m;
        m[RCode::RCODE_OK] = "成功处理!";
        m[RCode::RCODE_PARSE_FAILED] =  "消息解析失败!";
        m[RCode::RCODE_ERROR_MSGTYPE] =  "消息类型错误!";
        m[RCode::RCODE_INVALID_MSG] = "⽆效消息!";
        m[RCode::RCODE_DISCONNECTED] = "连接已断开!";
        m[RCode::RCODE_INVALID_PARAMS] = "⽆效的Rpc参数!";
        m[RCode::RCODE_NOT_FOUND_SERVICE] ="没有找到对应的服!";
        m[RCode::RCODE_INVALID_OPTYPE] = "⽆效的操作类型!";
        m[RCode::RCODE_NOT_FOUND_TOPIC] = "没有找到对应的主题!";
        m[RCode::RCODE_INTERNAL_ERROR] = "内部错误!";

        if(m.find(code) == m.end())
        {
            return std::string("未知错误");
        }
        return m[code];
    }

    // RPC请求类型定义
    enum class RType 
    {
        REQ_ASYNC = 0,
        REQ_CALLBACK
    };

    // 服务请求中的详细划分
    enum class ServiceRequestOpType
    {
        SERVICE_ONLINE = 0,
        SERVICE_OFFLINE,
        SERVICE_DISCOVERY,
        SERVICE_REGISTRY,
        SERVICE_UNKONW
    };

}